package com.huang.controller;

import cn.hutool.core.util.StrUtil;
import com.huang.enums.CommonCodeEnum;
import com.huang.resp.CommonResult;
import com.huang.security.properties.ClientProperties;
import com.huang.security.properties.SecurityProperties;
import com.huang.vo.TokenVo;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

/**
 * @author han
 * @since 2022-01-17 14:17:21
 */
@RestController
@RequestMapping("oauth")
public class TokenController {

    @Resource
    private RestTemplate restTemplate;

    @Resource
    private SecurityProperties securityProperties;


    @GetMapping("getToken/mobile")
    public CommonResult getTokenByMobile(String phone, String code) {
        String url = "%s?grant_type=%s&mobile=%s&code=%s&client_id=%s&client_secret=%s&scope=%s";
        ClientProperties client = securityProperties.getClient();
        String accessTokenUri = client.getAccessTokenUri();
        Assert.notNull(accessTokenUri, "accessTokenUri 不能为空,请配置 secure.client.accessTokenUri");
        String grantType = client.getGrantType();
        Assert.notNull(grantType, "grantType 不能为空,请配置 secure.client.grantType");
        String clientId = client.getClientId();
        Assert.notNull(clientId, "clientId 不能为空,请配置 secure.client.clientId");
        String clientSecret = client.getClientSecret();
        Assert.notNull(clientSecret, "clientSecret 不能为空,请配置 secure.client.clientSecret");
        String scope = client.getScope();
        Assert.notNull(scope, "scope 不能为空,请配置 secure.client.scope");

        if (StrUtil.isBlank(phone)) {
            return CommonResult.error(CommonCodeEnum.PARAM_ERROR);
        }
        if (StrUtil.isBlank(code)) {
            return CommonResult.error(CommonCodeEnum.PARAM_ERROR);
        }

        String trgUrl = String.format(url, accessTokenUri, grantType, phone, code, clientId, clientSecret, scope);
        return sendPost(trgUrl);
    }

    @GetMapping("getToken")
    public CommonResult getTokenByUsername(String phone, String code) {
        String  url = "%s?grant_type=%s&username=%s&password=%s&client_id=%s&client_secret=%s&scope=%s";
        ClientProperties client = securityProperties.getClient();
        String accessTokenUri = client.getAccessTokenUri();
        Assert.notNull(accessTokenUri, "accessTokenUri 不能为空,请配置 secure.client.accessTokenUri");
        String grantType = client.getGrantType();
        Assert.notNull(grantType, "grantType 不能为空,请配置 secure.client.grantType");
        String clientId = client.getClientId();
        Assert.notNull(clientId, "clientId 不能为空,请配置 secure.client.clientId");
        String clientSecret = client.getClientSecret();
        Assert.notNull(clientSecret, "clientSecret 不能为空,请配置 secure.client.clientSecret");
        String scope = client.getScope();
        Assert.notNull(scope, "scope 不能为空,请配置 secure.client.scope");

        if (StrUtil.isBlank(phone)) {
            return CommonResult.error(CommonCodeEnum.PARAM_ERROR);
        }
        if (StrUtil.isBlank(code)) {
            return CommonResult.error(CommonCodeEnum.PARAM_ERROR);
        }

        String trgUrl = String.format(url, accessTokenUri, grantType, phone, code, clientId, clientSecret, scope);
        return sendPost(trgUrl);
    }

    @PostMapping("refreshToken")
    public CommonResult getTokenByRefreshToken(@RequestParam("refreshToken") String refreshToken) {
        ClientProperties client = securityProperties.getClient();

        String accessTokenUri = client.getAccessTokenUri();
        Assert.notNull(accessTokenUri, "accessTokenUri 不能为空,请配置 secure.client.accessTokenUri");
        String grantType = "refresh_token";
        String clientId = client.getClientId();
        Assert.notNull(clientId, "clientId 不能为空,请配置 secure.client.clientId");
        String clientSecret = client.getClientSecret();
        Assert.notNull(clientSecret, "clientSecret 不能为空,请配置 secure.client.clientSecret");
        String scope = client.getScope();
        Assert.notNull(scope, "scope 不能为空,请配置 secure.client.scope");

        String url = "%s?grant_type=%s&client_id=%s&client_secret=%s&scope=%s&refresh_token=%s";
        String trgUrl = String.format(url, accessTokenUri, grantType, clientId, clientSecret, scope, refreshToken);

        return sendPost(trgUrl);
    }

    public CommonResult sendPost(String trgUrl) {
        HttpHeaders headers = new HttpHeaders();
        headers.add("User-Agent", "curl/7.58.0");
        headers.add("Content-Type", "application/json;charset=UTF-8");
        HttpEntity<String> entity = new HttpEntity<>(headers);

        ResponseEntity<TokenVo> accessTokenEntity = restTemplate.postForEntity(trgUrl, entity, TokenVo.class);
        return CommonResult.success(accessTokenEntity.getBody());
    }
}
